#ifndef __GlWindow_h__
#define __GlWindow_h__

#include <string>
#include <windows.h>

#include "GlMain.h"
#include "GlDistributor.h"
#include "GlWindowListener.h"

namespace GraphicLibrary
{
	class GlExport Window
		: public Distributor<WindowListener>
	{
		private:
			DWORD	mExStyle;
			DWORD	mStyle;
			HMENU	mMenu;

			RECT	mRect;

			HWND		mHwnd;
			std::string	mTitle;

			static	const char	msDefaultTitle[];

			void init(const UINT width, const UINT height, const int top, const int left, const char *title, const HWND pHwnd);
			static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
		public:
			inline Window(const UINT width, const UINT height)
				: mHwnd(0)
				, mTitle(msDefaultTitle)
			{
				init(width, height, 0, 0, msDefaultTitle, 0);
			}
			inline Window(const UINT width, const UINT height, const char *title)
				: mHwnd(0)
				, mTitle(title)
			{
				init(width, height, 0, 0, title, 0);
			}
			inline Window(const UINT width, const UINT height, const int top, const int left, const char *title)
				: mHwnd(0)
				, mTitle(title)
			{
				init(width, height, top, left, title, 0);
			}
			inline Window(const UINT width, const UINT height, const int top, const int left, const char *title, const Window *parent)
				: mHwnd(0)
				, mTitle(title)
			{
				init(width, height, top, left, title, parent->getHandler());
			}
			inline Window(const UINT width, const UINT height, const int top, const int left, const char *title, const HWND pHwnd)
				: mHwnd(0)
				, mTitle(title)
			{
				init(width, height, top, left, title, pHwnd);
			}
			virtual ~Window();
			void manage();
			inline RECT getRect() const						{return mRect;}
			inline UINT getClientAreaWidth() const			{return getRect().right - getRect().left;}
			inline UINT getClientAreaHeight() const			{return getRect().bottom - getRect().top;}
			inline float getClientAreaAcpectRatio() const	{return static_cast<float>(getClientAreaWidth()) / static_cast<float>(getClientAreaHeight());}
			inline void resize(const UINT width, const UINT height)
			{
				mRect.bottom = mRect.top + height;
				mRect.right = mRect.left + width;
				RECT rect;
				memcpy(&rect, &mRect, sizeof(RECT));
				AdjustWindowRectEx(&rect, mStyle, mMenu != 0, mExStyle);

				SetWindowPos(mHwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
			}
			inline void setTitle(const char *title)	{mTitle = title; SetWindowText(mHwnd, mTitle.c_str());}
			inline const char* getTitle() const		{return mTitle.c_str();}
			inline HWND getHandler() const			{return mHwnd;}
			static bool Init();
	};
}

#endif // __GlWindow_h__
